using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace AUSRIS.Reports.Utilities.Deployment.Entities
{
	/// <summary>
	/// Represents a report.
	/// </summary>
	public class Report : CatalogFile
	{
		#region Private Fields

		private string collapsedHeight;
		private int cacheTime;
		private IList<Parameter> parameters;
		private DataSource dataSource;

		#endregion

		#region Constructor(s)

		public Report(string name, Folder parentFolder, string sourcePath, string collapsedHeight, int cacheTime)
			: base(name, parentFolder, sourcePath )
		{
			if ( collapsedHeight != null && Util.ValidateDistance(collapsedHeight) )
			{
				this.collapsedHeight = collapsedHeight;
			}

			this.cacheTime = cacheTime;
			this.parameters = new List<Parameter>();
		}

		#endregion

		#region Properties

		public IList<Parameter> Parameters
		{
			get
			{
				return parameters;
			}
		}

		public string CollapsedHeight
		{
			get
			{
				return collapsedHeight;
			}
		}

		public int CacheTime
		{
			get
			{
				return cacheTime;
			}
		}

		public DataSource DataSource
		{
			get
			{
				return dataSource;
			}
			set
			{
				dataSource = value;
			}
		}

		#endregion

		public byte[] LoadDefinition()
		{
			FileStream stream = null;
			byte[] definition = null;

			try
			{
				stream = File.OpenRead(this.SourcePath);
				XmlDocument d = new XmlDocument();
				d.Load(stream);
				XmlNamespaceManager xnm = Util.GetXmlNamespaceManager(d);
				XmlDocument e = d;

				if (collapsedHeight != null)
				{
					e = CollapseHeight(d, xnm, collapsedHeight);
				}

				if (dataSource != null)
				{
					e = ConfigDataSource(e, xnm );
				}

				using (StringWriter sw = new StringWriter())
				{
					XmlTextWriter xtw = new XmlTextWriter(sw);
					e.WriteTo(xtw);
					definition = Util.StringToByteArray(sw.ToString());
					xtw.Close();
				}
			}
			finally
			{
				if (stream != null)
				{
					stream.Close();
				}
			}

			return definition;
		}



        /// <summary>
        /// Collapses the height.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="xnm">The namespace.</param>
        /// <param name="height">The height.</param>
        /// <returns></returns>
		private XmlDocument CollapseHeight(XmlDocument input, XmlNamespaceManager xnm, string height)
		{
			XmlDocument output = input;
			try
			{
				XmlNode n1 = output.SelectSingleNode("//def:Report/def:Body/def:Height", xnm);
				if (n1 != null)
				{
					n1.InnerText = height;
				}

			}
			catch(Exception)
			{}

			return output;
		}

        /// <summary>
        /// Configs the data source.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="xnm">The namespace.</param>
        /// <param name="dataSource">The data source.</param>
        /// <param name="targetFolder">The target folder.</param>
        /// <returns></returns>
		private XmlDocument ConfigDataSource(XmlDocument input, XmlNamespaceManager xnm )
		{
			XmlDocument output = input;
			if (dataSource.Publish)
			{
				string nodeXml = string.Format("<rd:DataSourceID>{0}</rd:DataSourceID><DataSourceReference>{1}</DataSourceReference>",
					Guid.NewGuid().ToString(),
					string.Format("{0}{1}", Util.GetRelativePath(Util.FormatPath(this.Path), this.dataSource.ParentPath), this.dataSource.Name)
					);

				try
				{
					XmlNode n1 = output.SelectSingleNode("//def:Report/def:DataSources/def:DataSource", xnm);
					if (n1 != null)
					{
						n1.InnerXml = nodeXml;
					}

				}
				catch(Exception)
				{}
			}
			return output;
		}
	}
}